package com.easylinkin.linkappapi.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.airconditioner.entity.AirDevice;
import com.easylinkin.linkappapi.airconditioner.entity.AirMonitorQuery;
import com.easylinkin.linkappapi.airconditioner.service.AirMonitorService;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.entity.DeviceRefAreaScope;
import com.easylinkin.linkappapi.device.service.DeviceRefAreaScopeService;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.codec.SerializationCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 *
 * redis 发布订阅请参考 https://www.jianshu.com/p/cb493e65fd35
 * @program: linkapp-group
 * @description: 空调adc设备监控
 * @author: chenkaixuan
 * @create: 2021-07-19 17:28
 */
@ServerEndpoint("/airDeviceMonitorListener/{tenantId}/{userId}")
@Component
public class AirMonitorListener extends Listener{
    @Value("${linkapp.openReceiving:true}")
    private Boolean openReceiving;
    private static final Logger LOGGER = LoggerFactory.getLogger(AirMonitorListener.class);
    private static CopyOnWriteArraySet<AirMonitorListener> webSocketSet = new CopyOnWriteArraySet<>();
    private static AirMonitorService service;
//    private static RedisUtil redisUtil;
//    private static DeviceMapper deviceMapper;
//    private static DeviceAttributeStatusService deviceAttributeStatusService;
    private static DeviceRefAreaScopeService deviceRefAreaScopeService;
//    private RequestModel<AirMonitorQuery> requestModel;

    @Resource
    private RedissonClient redisson;
    public static String WS_AIRMONITOR_LISTEN = "WS_AIRMONITOR_LISTEN";
    private RTopic topic;



    @Override
    @OnOpen
    public void onOpen(Session session, @PathParam("tenantId") String tenantId, @PathParam("userId") String userId) {
        init(session, tenantId, userId);
        // 加入set中
        webSocketSet.add(this);
    }

    /**
     * 连接关闭调用的方法
     */
    @Override
    @OnClose
    public void onClose() {
        LOGGER.info("通知关闭连接,用户id:{}", getUserId());
        // 从set中删除
        webSocketSet.remove(this);
    }

//    @Override
//    @OnMessage
//    public void onMessage(String message, Session session) {
//        LOGGER.info("收到通知会话消息,message:{},用户id:{}", message, this.getUserId());
//        if(StringUtils.isEmpty(message)){
//            return;
//        }
//        JSONObject jsonObject = JSONObject.parseObject(message);
//        if(jsonObject == null || jsonObject.isEmpty()){
//            return;
//        }
//        Page page = jsonObject.getObject("page", Page.class);
//        AirMonitorQuery airMonitorQuery =jsonObject.getObject("customQueryParams",AirMonitorQuery.class);
//        if(this.requestModel == null){
//            this.requestModel=new RequestModel<>();
//        }
//        this.requestModel.setCustomQueryParams(airMonitorQuery);
//        this.requestModel.setPage(page);
//        String msg = message(this.requestModel.getPage(),this.requestModel.getCustomQueryParams(), this.getTenantId(),null);
//        if(StringUtils.isEmpty(msg)){
//            return;
//        }
//        this.sendMessage(msg);
//    }
//
//    private String message(Page page,AirMonitorQuery airMonitorQuery,String tenantId,String deviceCode){
//        if(StringUtils.isEmpty(tenantId)){
//            return null;
//        }
//        if(airMonitorQuery == null){
//            airMonitorQuery=new AirMonitorQuery();
//        }
//        airMonitorQuery.setTenantId(tenantId);
//        if(!StringUtils.isEmpty(airMonitorQuery.getFunctionIdentifier())){
//            //空调
//            if(!StringUtils.isEmpty(deviceCode)){
//                //查询是否是设备分组绑定设备
//                QueryWrapper<DeviceRefAreaScope> deviceRefAreaScopeQueryWrapper = new QueryWrapper<>();
//                deviceRefAreaScopeQueryWrapper.eq("function_identifier",airMonitorQuery.getFunctionIdentifier());
//                deviceRefAreaScopeQueryWrapper.eq("tenant_id",airMonitorQuery.getTenantId());
//                deviceRefAreaScopeQueryWrapper.eq("device_code",deviceCode);
//                int count = deviceRefAreaScopeService.count(deviceRefAreaScopeQueryWrapper);
//                if(count<=0){
//                    //设备不是空调绑定设备，不推送消息
//                    return null;
//                }
//            }
//            Object resultDevice=null;
//            List<AirDevice> airDeviceListWS = service.getAirDeviceListWs(page, airMonitorQuery);
//            if(page != null){
//                resultDevice=page;
//            }else{
//                if(airDeviceListWS == null || airDeviceListWS.size()<=0){
//                    return null;
//                }
//                resultDevice=airDeviceListWS;
//            }
////            if(page != null){
////                IPage<AirDevice> airDevicePage = service.getAirDevicePage(page, airMonitorQuery);
////                if(airDevicePage == null || airDevicePage.getRecords() == null || airDevicePage.getRecords().size()<=0){
////                    return null;
////                }
////                resultDevice=airDevicePage;
////            }else{
////                List<AirDevice>  airDeviceList=service.getAirDeviceListWS(page,airMonitorQuery);
////                if(airDeviceList == null || airDeviceList.size()<=0){
////                    return null;
////                }
////                resultDevice=airDeviceList;
////            }
//            //查询数量
//            AirMonitorQuery airMonitorQuerycount=new AirMonitorQuery();
//            BeanUtils.copyProperties(airMonitorQuery,airMonitorQuerycount);
//            airMonitorQuerycount.setAirConditionStatus(null);
//            AirConditionStatistic airConditionStatistic = service.getAirConditionStatistic(airMonitorQuerycount);
//            HashMap<String, Object> map = new HashMap<>();
//            map.put("getAirDevicePage",resultDevice);
//            map.put("getAirConditionStatistic",airConditionStatistic);
//            String msg = JSONObject.toJSONString(map);
//            return  msg;
//        }else{
////            //设备
////            Device device = new Device();
////            device.setTenantId(tenantId);
////            List<Device> devices =null;
////            if(page !=null){
////                devices=deviceMapper.getMonitorDevices(page,device).getRecords();
////            }else{
////                devices=deviceMapper.getMonitorDevices(device);
////            }
////            for (Device device1 : devices) {
////                List<DeviceAttributeStatus> deviceAttributeList = device1.getDeviceAttributeStatusList();
////                deviceAttributeList = deviceAttributeStatusService.getFormatDeviceAttributeStatusList(deviceAttributeList);
////                device1.setDeviceAttributeStatusList(deviceAttributeList);
////            }
////            if(devices == null || devices.size()<=0){
////                return null;
////            }
////            String msg = JSONObject.toJSONString(devices);
////            return  msg;
//        }
//        return  null;
//    }


    /**
     * 开启监听
     */
    @PostConstruct
    void openReceiving() {
        if (!openReceiving) {
            return;
        }
        topic = redisson.getTopic(WS_AIRMONITOR_LISTEN, new SerializationCodec());
        LOGGER.info("监听ws成功：{}", topic);
        topic.addListener(Device.class, (charSequence, device) -> {
            send(device);
        });
    }

    public void sendNotice(Device device) {
//        redis 发广播
        try {
            topic.publish(device);
        } catch (Exception e) {
            LOGGER.error("sendNotice失败：", e);
        }


//        String key = WS_AIRMONITOR_LISTEN + UUID.randomUUID();
//        redisUtil.set(key+ "_param", device, 15);
//        //        10毫秒过期
//        redisUtil.setExpiredMilliseconds(key, "", 10);
    }

    /***
     * 消息推送
     * @param device
     */
    public void send(Device device) {
        if(StringUtils.isEmpty(device) || StringUtils.isEmpty(device.getCode()) || StringUtils.isEmpty(device.getTenantId())){
            return;
        }
        String functionIdentifier="air_conditioner";
        //查询是否是设备分组绑定设备
        QueryWrapper<DeviceRefAreaScope> deviceRefAreaScopeQueryWrapper = new QueryWrapper<>();
        deviceRefAreaScopeQueryWrapper.eq("function_identifier",functionIdentifier);
        deviceRefAreaScopeQueryWrapper.eq("tenant_id",device.getTenantId());
        deviceRefAreaScopeQueryWrapper.eq("device_code",device.getCode());
        int count = deviceRefAreaScopeService.count(deviceRefAreaScopeQueryWrapper);
        if(count<=0){
            //设备不是空调绑定设备，不推送消息
            return;
        }
        AirMonitorQuery airMonitorQuery = new AirMonitorQuery();
        airMonitorQuery.setFunctionIdentifier(functionIdentifier);
        airMonitorQuery.setTenantId(device.getTenantId());
        airMonitorQuery.setDeviceCode(device.getCode());
        List<AirDevice> airDeviceList = service.getAirDeviceListWs(null, airMonitorQuery);
        if(airDeviceList == null || airDeviceList.size()<=0){
            return;
        }
        AirDevice airDevice = airDeviceList.get(0);
        String msg = JSONObject.toJSONString(airDevice);
        for (AirMonitorListener listener : webSocketSet) {
            if(listener.getTenantId() != null && listener.getTenantId().equals(device.getTenantId())){
                listener.sendMessage(msg);
            }
//            if (listener.getTenantId() != null && listener.getTenantId().equals(device.getTenantId())) {
//                String message = message(listener.requestModel.getPage(),listener.requestModel.getCustomQueryParams(), listener.getTenantId(),device.getCode());
//                if(!StringUtils.isEmpty(message)){
//                    listener.sendMessage(message);
//                }
//            }
        }
    }



    @Resource
    public  void setService(AirMonitorService service) {
        AirMonitorListener.service = service;
    }
//    @Resource
//    public  void setDeviceService(DeviceMapper deviceMapper) {
//        AirMonitorListener.deviceMapper = deviceMapper;
//    }
//    @Resource
//    public  void setDeviceAttributeStatusService(DeviceAttributeStatusService deviceAttributeStatusService) {
//        AirMonitorListener.deviceAttributeStatusService = deviceAttributeStatusService;
//    }
    @Resource
    public  void setDeviceRefAreaScopeService(DeviceRefAreaScopeService deviceRefAreaScopeService) {
        AirMonitorListener.deviceRefAreaScopeService = deviceRefAreaScopeService;
    }
//    @Resource
//    public  void setRedisUtil(RedisUtil redisUtil) {
//        AirMonitorListener.redisUtil = redisUtil;
//    }
}
